/******************************************************************
 *  MRRM's testbench - instruction fetch unit                     *
 *                                                                *
 *  This file is part of the MRRM project                         *
 *  <http://mrrm.googlecode.com/>                                 *
 *                                                                *
 *  Author(s):                                                    *
 *    -  Wu Jinkai                                                *
 *                                                                *
 ******************************************************************
 *                                                                *
 *  Copyright (C) 2010 AUTHORS                                    *
 *                                                                *
 *  This source file may be used and distributed without          *
 *  restriction provided that this copyright statement is not     *
 *  removed from the file and that any derivative work contains   *
 *  the original copyright notice and the associated disclaimer.  *
 *                                                                *
 *  MRRM is free software: you can redistribute it and/or modify  *
 *  it under the terms of the GNU General Public License as       *
 *  published by the Free Software Foundation, either version 3   *
 *  of the License, or (at your option) any later version.        *
 *                                                                *
 *  MRRM is distributed in the hope that it will be useful, but   *
 *  WITHOUT ANY WARRANTY; without even the implied warranty of    *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  *
 *  GNU General Public License for more details.                  *
 *                                                                *
 *  You should have received a copy of the GNU General Public     *
 *  License along with MRRM. If not, see                          *
 *  <http://www.gnu.org/licenses/>.                               *
 *                                                                *
 ******************************************************************/

`include "global.v"

module mrrm_test_id;
  
parameter rw = `REGFILE_ADDR_WIDTH;
parameter mw = `MEMORY_ADDR_WIDTH;
parameter iw = `INSTRUCTION_WIDTH;
parameter ow = `OPERAND_WIDTH;

// Interfaces
// ID
reg [iw-1:0] D_insn;
reg [mw-1:0] D_valp;
wire [ow-1:0] d_vala;
wire [ow-1:0] d_valb;
wire [ow-1:0] d_valc;
wire [ow-1:0] d_vale;
wire [2:0] d_itype;
wire [1:0] d_isubtype;
wire [3:0] d_ifun;
wire d_snl;
wire [rw-1:0] d_dstx;
wire [rw-1:0] d_dsty;
wire d_wrx;
wire d_wry;

// RF
wire [rw-1:0] addra;
wire [rw-1:0] addrb;
wire [rw-1:0] addrc;
reg [ow-1:0] dataa;
reg [ow-1:0] datab;
reg [ow-1:0] datac;

// EXE
reg [rw-1:0] E_dstx;
reg [rw-1:0] E_dsty;
reg E_wrx;
reg E_wry;
reg [ow-1:0] e_valx;
reg [ow-1:0] e_valy;

// MEM
reg [2:1] M_itype;				// 2 bits are enough
reg M_snl;
reg [rw-1:0] M_dstx;
reg [rw-1:0] M_dsty;
reg M_wrx;
reg M_wry;
reg [ow-1:0] m_valm;
reg [ow-1:0] M_valx;
reg [ow-1:0] M_valy;

// WB
reg [2:1] W_itype;				// 2 bits are enough
reg W_snl;
reg [rw-1:0] W_dstx;
reg [rw-1:0] W_dsty;
reg W_wrx;
reg W_wry;
reg [ow-1:0] W_valm;
reg [ow-1:0] W_valx;
reg [ow-1:0] W_valy;

// Pipeline control
wire [rw-1:0] d_srca;
wire [rw-1:0] d_srcb;
wire [rw-1:0] d_srcc;

// Internal wires
wire [2:0] itype;
wire [1:0] isubtype;
wire [3:0] ifun;
wire snl;
wire [rw-1:0] rs1;
wire [rw-1:0] rs2;
wire [rw-1:0] rd1;
wire [rw-1:0] rd2;
wire [4:0] imm5;
wire [8:0] imm9;
wire [13:0] imm14;
	
mrrm_id temp_mrrm_id(
	// ID interface
	.D_insn(D_insn), .D_valp(D_valp), .d_vala(d_vala), .d_valb(d_valb), .d_valc(d_valc), .d_vale(d_vale),
	.d_itype(d_itype), .d_isubtype(d_isubtype), .d_ifun(d_ifun), .d_snl(d_snl), .d_dstx(d_dstx), .d_dsty(d_dsty), .d_wrx(d_wrx), .d_wry(d_wry),
	// RF interface
	.addra(addra), .addrb(addrb), .addrc(addrc), .dataa(dataa), .datab(datab), .datac(datac),
	// EXE interface
	.E_dstx(E_dstx), .E_dsty(E_dsty), .E_wrx(E_wrx), .E_wry(E_wry), .e_valx(e_valx), .e_valy(e_valy),
	// MEM interface
	.M_itype(M_itype), .M_snl(M_snl), .M_dstx(M_dstx), .M_dsty(M_dsty), .M_wrx(M_wrx), .M_wry(M_wry), .m_valm(m_valm), .M_valx(M_valx), .M_valy(M_valy),
	// WB interface
	.W_itype(W_itype), .W_snl(W_snl), .W_dstx(W_dstx), .W_dsty(W_dsty), .W_wrx(W_wrx), .W_wry(W_wry), .W_valm(W_valm), .W_valx(W_valx), .W_valy(W_valy),
	// Pipeline control interface
	.d_srca(d_srca), .d_srcb(d_srcb), .d_srcc(d_srcc)
	);
	
initial
  begin
  D_insn = 32'b00010010001101000000101111001101; //D_insn decides many control vactor!
	D_valp = 32'b00000000000000000000000000000000; //let them be different, so i can kown which one is chose
	dataa  = 32'b00000000000000000000000000000001;
	datab  = 32'b00000000000000000000000000000010;
	datac  = 32'b00000000000000000000000000000100;

	// EXE
	E_dstx = 32'b00000000000000000000000000000000;
	E_dsty = 32'b00000000000000000000000000000000;
	E_wrx = 0;
	E_wry = 0;
	e_valx = 32'b00000000000000000000000000001000;
	e_valy = 32'b00000000000000000000000000010000;

	// MEM
	M_itype = 2'b00;				// 2 bits are enough
	M_snl = 0;
	M_dstx = 32'b00000000000000000000000000000000;
	M_dsty = 32'b00000000000000000000000000000000;
	M_wrx  = 32'b00000000000000000000000000100000;
	M_wry  = 32'b00000000000000000000000001000000;
	m_valm = 32'b00000000000000000000000010000000;
	M_valx = 32'b00000000000000000000000100000000;
	M_valy = 32'b00000000000000000000001000000000;

// WB
	W_itype = 2'b00;				// 2 bits are enough
	W_snl = 0;
	W_dstx = 32'b00000000000000000000000000000000;
	W_dsty = 32'b00000000000000000000000000000000;
	W_wrx = 0;
	W_wry = 0;
	W_valm = 32'b00000000000000000000010000000000;
	W_valx = 32'b00000000000000000000100000000000;
	W_valy = 32'b00000000000000000001000000000000;
  
  
  //test d_vala
  #20 D_insn = 32'b10110011001101000000101111001101;
  #20 D_insn = 32'b01000011001101000000101111001101;
  E_wrx = 1;
  E_dstx = 32'b00000000000000000000000000000110;
  #20 E_wrx = 0;
  E_wry = 1;
  E_dsty = 32'b00000000000000000000000000000110;
  #20 E_wry = 0;
  M_itype[2:1] = 2'b01;
  M_snl = 1;
  M_dstx = 32'b00000000000000000000000000000110;
  #20 M_snl = 0;
  M_wrx = 1;
  M_dstx = 32'b00000000000000000000000000000110;
  #20 M_wrx = 0;
  M_wry = 1;
  M_dsty = 32'b00000000000000000000000000000110;
  #20 M_wry = 0;
  W_itype[2:1] = 2'b01;
  W_snl = 1;
  W_dstx = 32'b00000000000000000000000000000110;
  #20 W_snl = 0;
  W_wrx = 1;
  W_dstx = 32'b00000000000000000000000000000110;
  #20 W_wrx = 0;
  W_wry = 1;
  W_dsty = 32'b00000000000000000000000000000110;
  #20 W_wry = 0;
  
  //test d_valb
  #120 D_insn = 32'b00110011001101000000101111001101;
  #20 D_insn = 32'b01100011001101000000101111001101;
  #20 D_insn = 32'b01000011001101000000101111001001;
  E_wrx = 1;
  E_dstx = 32'b00000000000000000000000000001001;
  #20 E_wrx = 0;
  E_wry = 1;
  E_dsty = 32'b00000000000000000000000000001001;
  
  #20 E_wry = 0;
  M_itype[2:1] = 2'b01;
  M_snl = 1;
  M_dstx = 32'b00000000000000000000000000001001;
  #20 M_snl = 0;
  M_wrx = 1;
  M_dstx = 32'b00000000000000000000000000001001;
  #20 M_wrx = 0;
  M_wry = 1;
  M_dsty = 32'b00000000000000000000000000001001;
  
  #20 M_wry = 0;
  W_itype[2:1] = 2'b01;
  W_snl = 1;
  W_dstx = 32'b00000000000000000000000000001001;
  #20 W_snl = 0;
  W_wrx = 1;
  W_dstx = 32'b00000000000000000000000000001001;
  #20 W_wrx = 0;
  W_wry = 1;
  W_dsty = 32'b00000000000000000000000000001001;
  
  #20 W_wry = 0;
  
  //test d_valc
  #120 D_insn = 32'b01010011001101000000101011001101;
  #20  D_insn = 32'b01110011001101000000101011001101;
  
  
  //test d_vale
  #120 D_insn = 32'b00110011001101111100101111001101;
  
  #20 D_insn =  32'b01000011001101010100101111001001;
  E_wrx = 1;
  E_dstx = 32'b00000000000000000000000000010101;
  #20 E_wrx = 0;
  E_wry = 1;
  E_dsty = 32'b00000000000000000000000000010101;
  
  #20 E_wry = 0;
  M_itype[2:1] = 2'b01;
  M_snl = 1;
  M_dstx = 32'b00000000000000000000000000010101;
  #20 M_snl = 0;
  M_wrx = 1;
  M_dstx = 32'b00000000000000000000000000010101;
  #20 M_wrx = 0;
  M_wry = 1;
  M_dsty = 32'b00000000000000000000000000010101;
  
  #20 M_wry = 0;
  W_itype[2:1] = 2'b01;
  W_snl = 1;
  W_dstx = 32'b00000000000000000000000000001001;
  #20 W_snl = 0;
  W_wrx = 1;
  W_dstx = 32'b00000000000000000000000000001001;
  #20 W_wrx = 0;
  W_wry = 1;
  W_dsty = 32'b00000000000000000000000000001001;
  
  #20 W_wry = 0;
  
  
  //test d_srca,b,c
  #120 D_insn = 32'b01010011001101000000101011001101;
  #20  D_insn = 32'b11010011001101000000101011001101;
  
  #20  D_insn = 32'b01010011001101000000101011001101;
  #20  D_insn = 32'b11010011001101000000101011001101;
  
  #20  D_insn = 32'b01010010001101000000101011001101;
  #20  D_insn = 32'b00010011001101000000101011001101;

  #100 $stop;

end
  
initial
  begin
    $monitor("Time@%d, d_vala=%h,d_valb=%h,d_valc=%h,d_vale=%h,d_itype=%h,d_isubtype=%h,d_ifun=%h,d_snl=%h, d_dstx=%h,d_dsty=%h,d_wrx=%h,d_wry=%h,addra=%h,addrb=%h,addrc=%h, d_srca=%h,d_srcb=%h,d_srcc=%h",
      $time, d_vala,d_valb,d_valc,d_vale,d_itype,d_isubtype,d_ifun,d_snl, d_dstx,d_dsty,d_wrx,d_wry,addra,addrb,addrc, d_srca,d_srcb,d_srcc
    );
end

endmodule